package com.yonyou.wdt.job;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yonyou.wdt.entity.DataConnectionTypeEnum;
import com.yonyou.wdt.entity.QueryDto;
import com.yonyou.wdt.job.config.BaseConfig;
import com.yonyou.wdt.qimenmodel.qimencloud.api.scenehu3cgwt0tc.request.WdtStockInDtlQueryRequest;
import com.yonyou.wdt.qimenmodel.qimencloud.api.scenehu3cgwt0tc.response.WdtStockInDtlQueryResponse;
import com.yonyou.wdt.service.YonsuiteService;
import com.yonyou.wdt.utils.DateUtils;
import com.yonyou.wdt.utils.ReSubmitUtil;
import com.yonyou.wdt.utils.WdtClient;
import com.yonyou.wdt.utils.WdtConfigProperties;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ZLY
 * @data 2024/6/12
 * @User PC
 * @Msg 旺店通采购入库单同步YS采购入库单
 */
@Component
public class WdtPurchaseInToYs extends BaseConfig {

    private final WdtConfigProperties configProperties;

    private static final Logger logger = LoggerFactory.getLogger(WdtPurchaseInToYs.class);

    @Resource
    private YonsuiteService yonsuiteService;
    private static final String JOB_CLASS="maoEr010";

    public WdtPurchaseInToYs(WdtConfigProperties configProperties) {
        this.configProperties = configProperties;
    }

    @XxlJob("WdtPurchaseInToYs")
    public ReturnT<String> WdtPurchaseReturnToYs(String params) throws Exception {

        String param = XxlJobHelper.getJobParam();
        Map<String, Object> map = new HashMap<>();
        if (param != null && !param.isEmpty()) {
            List<String> timeRange = Arrays.asList(param.split("\\|"));
            if (timeRange.size() == 2) {
                map.put("start_time", timeRange.get(0));
                map.put("end_time", timeRange.get(1));
            } else {
                // 使用单据号同步
                map.put("stockin_no", param);
            }
        } else {
            map.put("start_time", DateUtils.getStartDateBy10m());
            map.put("end_time", DateUtils.getEndDateBy10m());
        }
        // 处理相关业务
        QueryDto dto = new QueryDto();
        dto.setTenantId(getYsTenantId());
        dto.setAppKey(getYsAppKey());
        dto.setAppSecret(getYsAppSecret());
        // 获取YS系统租户动态域名信息
        ReturnT<String> isReturn2 = getYsDynamicDomainName(JOB_CLASS,dto);
        // 域名获取失败
        if (isReturn2 != null) return isReturn2;
        try {
            // 旺店通采购入库单查询API对象
            List<JSONObject> transferInList = sendWdt(map);
            //解析数据，组装YS请求参数
            if (!transferInList.isEmpty()) {
                for (JSONObject jsonObject : transferInList) {
                    ArrayList<JSONObject> ysPurchaseRecord = this.getYsPurchaseRecord(jsonObject, dto);
                    //旺店通采购入库单号
                    String wdtCode = jsonObject.getStr("order_no");
                    if (ysPurchaseRecord.size() > 0) {
                        Map<String, List<JSONObject>> groupByIdMap = groupById(ysPurchaseRecord);
                        for (Map.Entry<String, List<JSONObject>> idKey : groupByIdMap.entrySet()) {
                            List<JSONObject> value = idKey.getValue();
                            Map<String, Object> data = saveYsPurinrecord(value, jsonObject);
                            //YS采购入库来源生单保存
                            JSONObject response = yonsuiteService.purchaseInMerge(data, dto);
                            if (null != response && "200".equals(response.getStr("code"))) {
                                logger.info("旺店通采购入库：{}保存YS采购入库来源生单成功", wdtCode);
                                InsertLogger(JOB_CLASS,wdtCode, "1", "旺店通采购入库单:"+wdtCode+"保存YS采购入库" + response.getJSONObject("data").getStr("code") + "成功");
                            } else {
                                if (null != response) {
                                    logger.error("旺店通采购入库：{}保存YS采购入库来源生单失败：{}", wdtCode, response.getStr("message"));
                                    InsertLogger(JOB_CLASS,wdtCode, "0", "旺店通采购入库单:"+wdtCode+"保存YS采购入库失败"+response.getStr("message"));
                                } else {
                                    logger.error("旺店通采购入库：{}保存YS采购入库来源生单失败，YS接口未返回数据", wdtCode);
                                    InsertLogger(JOB_CLASS,wdtCode, "0", "旺店通采购入库单:"+wdtCode+"保存YS采购入库失败"+response.getStr("message"));
                                }
                                return ReturnT.FAIL;
                            }
                        }
                    } else {
                        logger.error("旺店通采购入库：{}保存YS采购入库来源生单失败，YS采购订单没有查询到对应单据", wdtCode);
                        InsertLogger(JOB_CLASS,wdtCode, "0", "失败，YS系统中采购订单没有查询到对应单据");

                    }
                }
            }
        } catch (Exception e) {
            logger.error("Error occurred", e);
            logger.error("旺店通采购入库同步YS采购入库单失败：{}", e.toString());
            return new ReturnT<>(ReturnT.FAIL_CODE, "旺店通采购入库同步YS采购入库单失败：" + e.getMessage());
        }
        logger.info("  --  旺店通采购入库同步YS采购入库单单任务执行完成  --  ");
        return ReturnT.SUCCESS;
    }

    /**
     * @param ysPurchaseRecord ys采购订单查询返参
     * @param jsonObject       旺店通采购入库查询返参
     * @return 采购入库来源生单保存入参组装
     */
    private Map<String, Object> saveYsPurinrecord(List<JSONObject> ysPurchaseRecord, JSONObject jsonObject) {
        ArrayList<Map<String, Object>> purInRecords = new ArrayList<>();

        HashMap<String, Object> purSaveMap = new HashMap<>();
        purSaveMap.put("mergeSourceData", true);
        purSaveMap.put("needCalcLines", true); //为true时，以数量进行件数、计价数量相关反算
        purSaveMap.put("calcLinesKey","oriTaxUnitPrice"); //表体行计算依据，不传或传入null时默认原币无税金额（oriMoney）
        purSaveMap.put("warehouse",jsonObject.getStr("warehouse_no")); //仓库id，或仓库code；上游单据未指定仓库时必输
       purSaveMap.put("code",jsonObject.get("order_no")); //单据编码 系统设置为手工编号时必输，系统设置为自动编号时非必输
        purSaveMap.put("bustype","A15001"); //交易类型 业务流中未配置交易类型且未设置默认交易类型时必输。
        /*long createdTime = jsonObject.get("created_time").getAsLong();
        String createdDate = convertTimestamp(createdTime);*/
        String modified = jsonObject.getStr("modified");
        purSaveMap.put("vouchdate", modified);
        purSaveMap.put("_status", "Insert");
        //
        HashMap<String, Object> defMap = new HashMap<>();
        defMap.put("maoer05",jsonObject.get("order_no"));
        purSaveMap.put("purInRecordDefineCharacter",defMap);

        JSONArray wdtDetails = jsonObject.getJSONArray("details_list");
        //循环旺店通子表
        for (int i = 0; i < wdtDetails.size(); i++) {
            JSONObject wdtData = (JSONObject)wdtDetails.get(i);
            String wdtGoogsNo = wdtData.getStr("goods_no");
            //循环YS子表进行对比
            for (JSONObject ysData : ysPurchaseRecord) {
                String productCode = (String) ysData.get("product_cCode");
                if (productCode.equals(wdtGoogsNo)) {
                    HashMap<String, Object> purInRecordsMaps = new HashMap<>();
                    //purInRecordsMaps.put("makeRuleCode", "st_purchaseorder");//生单规则编码，固定值。订单入库：st_purchaseorder，采购订单退库：st_purchaseorder3，退货订单退库：st_purchaseorder_return，到货入库：pu_arrivalorder，退货单退库：pu_arrivalorder_red
                    purInRecordsMaps.put("makeRuleCode", "st_purchaseorder");
                    purInRecordsMaps.put("sourceid", ysData.getStr("id")); //主表ID
                    purInRecordsMaps.put("sourceautoid", ysData.getStr("purchaseOrders_id")); //子表ID
                    purInRecordsMaps.put("qty", wdtData.getBigDecimal("goods_count"));
                    purInRecordsMaps.put("oriTaxUnitPrice", ysData.get("oriTaxUnitPrice")); //含税单价
                    purInRecordsMaps.put("_status", "Insert");
                    purInRecordsMaps.put("batchno", StringUtils.isBlank(wdtData.getStr("batch"))?"202412":wdtData.getStr("batch"));
                    purInRecordsMaps.put("invaliddate", StringUtils.isBlank(wdtData.getStr("expire_date"))  || wdtData.getStr("expire_date").substring(0,10).equals("0000-00-00")?"2027-12-31":wdtData.getStr("expire_date"));

                    purInRecords.add(purInRecordsMaps);
                }
            }
        }
        purSaveMap.put("purInRecords", purInRecords);
        //purSaveMap.put("resubmitCheckKey", jsonObject.getStr("order_no"));
        ReSubmitUtil.resubmitCheckKey(purSaveMap);
        HashMap<String, Object> SaveMap = new HashMap<>();
        SaveMap.put("data", purSaveMap);
        return SaveMap;
    }


    /**
     * @return
     * @Author Yjy
     * @Description 发送请求查询旺店通数据
     * @Date 2024/06/04
     * @Param
     **/
    private List<JSONObject> sendWdt(Map<String, Object> map) throws Exception {
        Integer pageSize=40;
        map.put("page_size",40);
        Integer pageIndex = 0;
        ArrayList<JSONObject> purInList = new ArrayList<>();
        WdtClient client = new WdtClient(configProperties.getSid(), configProperties.getKey(), configProperties.getSecret(), configProperties.getUrl());
        while (true) {
            map.put("page_no",pageIndex);
            String execute = client.execute("stockin_order_query_purchase.php", map);
            JSONObject response = JSONUtil.parseObj(execute);
            if (null != response && response.getInt("code") == 0) {
                int totalCount = response.getInt("total_count");
                // 旺店通接口查询频率问题处理
                this.APICurrentLimiting("stockin_order_query_purchase.php",59);
                List<JSONObject> list = JSONUtil.toList(response.getJSONArray("stockin_list"), JSONObject.class);
                if (!list.isEmpty()){
                    com.yonyou.wdt.qimenmodel.qimencloud.api.DefaultQimenCloudClient qmClient = new com.yonyou.wdt.qimenmodel.qimencloud.api.DefaultQimenCloudClient(configProperties.getQmServerUrl(), configProperties.getQmAppKey(), configProperties.getQmAppSecret(), "json");

                    //resList.addAll(JSONUtil.toList(orderArray, JSONObject.class));
                        for (JSONObject entries : list) {
                            ArrayList<JSONObject> dtlList = new ArrayList<>();
                            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
                            String stockOutNo = entries.getStr("order_no");
                            stringObjectHashMap.put("stockin_no",stockOutNo);
                            Boolean flag=true;
                            Integer dtlTotalCount=0;
                            Integer dtlTotalPage=0;
                            Integer dtlRealityPageNo = 0;
                            while (flag){
                                stringObjectHashMap.put("page_no",dtlRealityPageNo.toString());
                                stringObjectHashMap.put("page_size",100);
                                WdtStockInDtlQueryRequest dtlReq = this.setStockInDtlModel(stringObjectHashMap, configProperties.getQmTargetAppKey(), configProperties.getSid());
                                WdtStockInDtlQueryResponse dtlRes = null;
                                try {
                                    dtlRes = qmClient.execute(dtlReq);
                                } catch (com.yonyou.wdt.qimenmodel.taobao.api.ApiException e) {
                                    throw new RuntimeException(e);
                                }
                                JSONObject dtlJson = JSONUtil.parseObj(dtlRes.getBody()).getJSONObject("response");
                                if ("0".equals(dtlJson.getStr("errorcode"))) {
                                    //判断分页
                                    if (dtlRealityPageNo == 0) {
                                        dtlTotalCount = dtlJson.getInt("total_count", 0);
                                        dtlTotalPage = dtlTotalCount % 100 == 0 ? dtlTotalCount / 100 : dtlTotalCount / 100 + 1;
                                    }
                                    //每页订单列表
                                    JSONArray dtlJosn = dtlJson.getJSONArray("stockin_batch_detail");
                                    dtlList.addAll(JSONUtil.toList(dtlJosn,JSONObject.class));
                                }else {
                                    InsertLogger(JOB_CLASS,stockOutNo, "0", "旺店通入库批次接口查询失败" + dtlJson.getStr("message"));
                                    break;
                                }
                                this.APICurrentLimiting("wdt.stockin.batch.detail",59);
                                if (dtlTotalPage > dtlRealityPageNo + 1) {
                                    dtlRealityPageNo += 1;
                                } else {
                                    flag = false;
                                }
                            }


                            JSONArray jsonArray = entries.getJSONArray("details_list");
                            JSONArray newDetail = new JSONArray();
                            for (Object obj : jsonArray) {
                                JSONObject entries1 = JSONUtil.parseObj(obj);
                                Optional<JSONObject> any = dtlList.stream().filter(o -> o.getStr("goods_no").equals(entries1.getStr("goods_no"))).findAny();
                                if (any.isPresent()){
                                    entries1.set("batch",any.get().getStr("batch"));
                                    String substring = any.get().getStr("expire_date").substring(0, 10);
                                    if (!substring.equals("0000-00-00")){
                                        entries1.set("expire_date", substring);
                                    }else {
                                        entries1.set("expire_date", "");
                                    }
                                }

                                newDetail.add(entries1);
                            }
                            entries.set("details_list",newDetail);
                            purInList.add(entries);
                    }
                }
                Integer page=pageIndex+1;
                if (totalCount < page * pageSize) {
                    break;
                } else {
                    pageIndex++;
                }
            } else {
                if (response != null) {
                    logger.error("查询旺店通采购入库单异常：{}，请重试", response.getStr("message"));
                    return null;
                } else {
                    logger.error("查询旺店通采购入库单异常：旺店通接口返回数据为空，请重试");
                    return null;
                }
            }
        }
        logger.info("当前时间段：" + map.get("start_time") + "-" + map.get("end_time") + "采购入库单数据共有：" + purInList.size() + "条");
        return purInList;
    }



    /**
     * @return
     * @Author Huangwb
     * @Description 根据单据id进行分组(主子表合并)
     * @Date 18:11 2023/5/11
     * @Param
     **/
    private Map<String, List<JSONObject>> groupById(ArrayList<JSONObject> ysPurinrecordList) {
        return ysPurinrecordList.stream().collect(Collectors.groupingBy(jsonObject -> jsonObject.getStr("id")));
    }

    /**
     * @return
     * @Author Huangwb
     * @Description 时间戳格式转换
     * @Date 17:36 2023/5/30
     * @Param
     **/
    public static String convertTimestamp(long timestamp) {
        Date date = new Date(timestamp);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(date);
    }
}
